package com.xuetang.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xuetang.entity.Article;
import com.xuetang.entity.ArticleCategory;
import com.xuetang.entity.ArticleFavorite;
import com.xuetang.entity.ArticleTag;
import com.xuetang.mapper.ArticleCategoryMapper;
import com.xuetang.mapper.ArticleFavoriteMapper;
import com.xuetang.mapper.ArticleMapper;
import com.xuetang.mapper.ArticleTagMapper;
import com.xuetang.service.ArticleService;

/**
 * 文章服务实现类
 */
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Autowired
    private ArticleFavoriteMapper articleFavoriteMapper;

    @Autowired
    private ArticleCategoryMapper articleCategoryMapper;

    @Override
    @Transactional
    public Article saveArticle(Article article, List<String> tags) {
        // 设置时间
        Date now = new Date();
        if (article.getId() == null) {
            article.setCreatedAt(now);
            article.setViewCount(0);
            article.setLikeCount(0);
            article.setFavoriteCount(0);

            // 插入文章
            articleMapper.insert(article);
        } else {
            article.setUpdatedAt(now);

            // 更新文章
            articleMapper.updateById(article);
        }

        // 保存标签
        if (tags != null && !tags.isEmpty()) {
            // 先删除原有标签
            articleTagMapper.deleteByArticleId(article.getId());

            // 添加新标签
            List<ArticleTag> articleTags = new ArrayList<>();
            for (String tag : tags) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(article.getId());
                articleTag.setTag(tag);
                articleTags.add(articleTag);
            }

            // 批量插入标签
            articleTagMapper.batchInsert(articleTags);
        }

        return article;
    }

    @Override
    public Article getArticleById(Long id) {
        Article article = articleMapper.selectById(id);
        if (article != null) {
            // 获取文章标签
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(id);
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }
        return article;
    }

    @Override
    public Article getArticleWithFavoriteStatus(Long id, Long userId) {
        Article article = getArticleById(id);
        if (article != null && userId != null) {
            boolean isFavorite = articleFavoriteMapper.countByUserIdAndArticleId(userId, id) > 0;
            article.setIsFavorite(isFavorite);
        }
        return article;
    }

    @Override
    @Transactional
    public boolean deleteArticle(Long id) {
        // 删除文章标签
        articleTagMapper.deleteByArticleId(id);

        // 删除文章
        return articleMapper.deleteById(id) > 0;
    }

    @Override
    public Map<String, Object> getArticleList(Integer page, Integer size, String category, String keyword) {
        int offset = (page - 1) * size;
        List<Article> articles;
        int total;

        if (keyword != null && !keyword.isEmpty()) {
            // 关键字搜索
            articles = articleMapper.searchArticles(keyword, offset, size);
            total = articleMapper.countSearchArticles(keyword);
        } else if (category != null && !category.equals("all")) {
            // 按分类查询
            articles = articleMapper.selectByCategory(category, offset, size);
            total = articleMapper.countByCategory(category);
        } else {
            // 查询所有已发布文章
            articles = articleMapper.selectPage(offset, size);
            total = articleMapper.countAll();
        }

        // 获取文章标签
        for (Article article : articles) {
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("list", articles);
        result.put("total", total);
        return result;
    }

    @Override
    public List<Article> getRecommendedArticles(Integer limit) {
        List<Article> articles = articleMapper.selectRecommended(0, limit);

        // 获取文章标签
        for (Article article : articles) {
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }

        return articles;
    }

    @Override
    public List<Article> getHotArticles(Integer limit) {
        List<Article> articles = articleMapper.selectHotArticles(0, limit);

        // 获取文章标签
        for (Article article : articles) {
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }

        return articles;
    }

    @Override
    @Transactional
    public boolean incrementViewCount(Long id) {
        return articleMapper.incrementViewCount(id) > 0;
    }

    @Override
    @Transactional
    public boolean likeArticle(Long id) {
        return articleMapper.incrementLikeCount(id) > 0;
    }

    @Override
    @Transactional
    public boolean toggleFavorite(Long articleId, Long userId) {
        boolean isFavorite = articleFavoriteMapper.countByUserIdAndArticleId(userId, articleId) > 0;

        if (isFavorite) {
            // 取消收藏
            articleFavoriteMapper.deleteByUserIdAndArticleId(userId, articleId);
            articleMapper.decrementFavoriteCount(articleId);
            return false;
        } else {
            // 添加收藏
            ArticleFavorite favorite = new ArticleFavorite();
            favorite.setArticleId(articleId);
            favorite.setUserId(userId);
            favorite.setCreatedAt(new Date());
            articleFavoriteMapper.insert(favorite);
            articleMapper.incrementFavoriteCount(articleId);
            return true;
        }
    }

    @Override
    public Map<String, Object> getUserFavoriteArticles(Long userId, Integer page, Integer size) {
        int offset = (page - 1) * size;
        List<ArticleFavorite> favorites = articleFavoriteMapper.selectByUserId(userId, offset, size);
        int total = articleFavoriteMapper.countByUserId(userId);

        List<Article> articles = new ArrayList<>();
        for (ArticleFavorite favorite : favorites) {
            Article article = articleMapper.selectById(favorite.getArticleId());
            if (article != null) {
                // 获取文章标签
                List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
                List<String> tags = new ArrayList<>();
                for (ArticleTag tag : articleTags) {
                    tags.add(tag.getTag());
                }
                article.setTags(tags);
                article.setIsFavorite(true);
                articles.add(article);
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("list", articles);
        result.put("total", total);
        return result;
    }

    @Override
    public boolean isArticleFavorited(Long articleId, Long userId) {
        return articleFavoriteMapper.countByUserIdAndArticleId(userId, articleId) > 0;
    }

    @Override
    public List<ArticleCategory> getCategories() {
        return articleCategoryMapper.selectAllOrderBySort();
    }

    @Override
    @Transactional
    public ArticleCategory saveCategory(ArticleCategory category) {
        Date now = new Date();
        if (category.getId() == null) {
            category.setCreatedAt(now);
            articleCategoryMapper.insert(category);
        } else {
            category.setUpdatedAt(now);
            articleCategoryMapper.updateById(category);
        }
        return category;
    }

    @Override
    @Transactional
    public boolean deleteCategory(Long id) {
        return articleCategoryMapper.deleteById(id) > 0;
    }

    @Override
    public Map<String, Object> getArticlesByCategory(String category, Integer page, Integer size) {
        int offset = (page - 1) * size;
        List<Article> articles = articleMapper.selectByCategory(category, offset, size);
        int total = articleMapper.countByCategory(category);

        // 获取文章标签
        for (Article article : articles) {
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("list", articles);
        result.put("total", total);
        return result;
    }

    @Override
    public Map<String, Object> searchArticles(String keyword, Integer page, Integer size) {
        int offset = (page - 1) * size;
        List<Article> articles = articleMapper.searchArticles(keyword, offset, size);
        int total = articleMapper.countSearchArticles(keyword);

        // 获取文章标签
        for (Article article : articles) {
            List<ArticleTag> articleTags = articleTagMapper.selectByArticleId(article.getId());
            List<String> tags = new ArrayList<>();
            for (ArticleTag tag : articleTags) {
                tags.add(tag.getTag());
            }
            article.setTags(tags);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("list", articles);
        result.put("total", total);
        return result;
    }

    @Override
    public List<String> getAllTags() {
        return articleTagMapper.selectAllTags();
    }
}